﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Diagnostics;

namespace XNADota.Graphics.Techniques
{
    public enum EPostScreen : int
    {
        BlurPostScreen = 0,
        OutLinePostScreen = 1,
        OppositePostScreen = 2,

        PostScreenCount,
    }

    internal class BlurPostScreen : Technique
    {
        public BlurPostScreen()
            : base("Techniques//BlurPostScreen")
        {
            _Effect.Parameters["BlurDistance"].SetValue(0.01f);
        }
    }

    internal class OutLinePostScreen : Technique
    {
        public OutLinePostScreen()
            : base("Techniques//OutLinePostScreen")
        {
            _Effect.Parameters["Thickness"].SetValue(1.5f);
            _Effect.Parameters["Threshold"].SetValue(0.2f);
        }
    }

    internal class OppositePostScreen : Technique
    {
        public OppositePostScreen()
            : base("Techniques//OppositePostScreen")
        {
        }
    }

    public class PostScreenFactory
    {
        public static Technique CreatePostScreenTechnique(EPostScreen type)
        {
            switch (type)
            {
                case EPostScreen.BlurPostScreen:
                    return new BlurPostScreen();
                    break;
                case EPostScreen.OutLinePostScreen:
                    return new OutLinePostScreen();
                    break;
                case EPostScreen.OppositePostScreen:
                    return new OppositePostScreen();
                    break;
            }

            Debug.Assert(false);
            return null;
        }
    }

    class PostScreen : GameComponent
    {
        private SpriteBatch _SpriteBatch;
        private Dictionary<EPostScreen, Technique> _PostScreens;
        private EPostScreen _PostScreenType;

        public PostScreen(Game game) : base(game)
        {
            _SpriteBatch = new SpriteBatch(game.GraphicsDevice);

            _PostScreens = new Dictionary<EPostScreen,Technique>();
            for (int i = 0; i < (int)EPostScreen.PostScreenCount; i++)
            {
                EPostScreen type = (EPostScreen)Enum.ToObject(typeof(EPostScreen), i);
                _PostScreens.Add(type, PostScreenFactory.CreatePostScreenTechnique(type));
            }

            _PostScreenType = EPostScreen.BlurPostScreen;
            Enabled = false;
        }

        public void Render()
        {
            if (Enabled == false) return;
            
            // start screen post
            var ScreenShot = new ResolveTexture2D(this.Game.GraphicsDevice,
                                                  this.Game.GraphicsDevice.Viewport.Width,
                                                  this.Game.GraphicsDevice.Viewport.Height,
                                                  1,
                                                  SurfaceFormat.Color);

            // Get data with help of the resolve method
            this.Game.GraphicsDevice.ResolveBackBuffer(ScreenShot);

            _SpriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);

            _PostScreens[_PostScreenType].Begin();

            _SpriteBatch.Draw(ScreenShot, new Rectangle(0, 0, ScreenShot.Width, ScreenShot.Height), Color.White);

            _PostScreens[_PostScreenType].End();

            _SpriteBatch.End();
        }
    }
}
